using System.Collections.Generic;
using MyFramework.Singleton;
using UnityEngine;
using Object = UnityEngine.Object;

namespace MyFramework.Pool
{
    /// <summary>
    /// 缓存池模块
    /// </summary>
    public class GameObjectPool : Singleton<GameObjectPool>
    {
        private readonly Dictionary<string, GameObject> _pool = new();

        /// <summary>
        /// 初始对象个数，根据性能分级改变
        /// </summary>
        private const uint InitialCount = 20u;

        /// <summary>
        /// 池子最大容量，根据性能分级改变
        /// </summary>
        private const uint Capacity = 30u;

        public void Init(GameObject prefab)
        {
            GameObject go;
            for (int i = 0; i < InitialCount; i++)
            {
                go = Object.Instantiate(prefab);
                _pool[i.ToString()] = go;
                go.SetActive(false);
            }
        }

        /// <summary>
        /// 拿
        /// </summary>
        /// <param name="objName"></param>
        /// <returns></returns>
        public GameObject Get(string objName)
        {
            GameObject tempObj;

            if (_pool.ContainsKey(objName) && _pool.Count > 0)
            {
                tempObj = _pool[objName];
                _pool.Remove(objName);
            }
            else
            {
                tempObj = Object.Instantiate(Resources.Load<GameObject>(objName));
                tempObj.name = objName;
            }

            tempObj.SetActive(true);
            return tempObj;
        }

        /// <summary>
        /// 放回
        /// </summary>
        /// <param name="objName"></param>
        /// <param name="go"></param>
        public void Push(string objName, GameObject go)
        {
            go.SetActive(false);

            if (_pool.Count >= Capacity)
            {
                _pool[objName] = go;
            }
            else
            {
                Object.Destroy(go);
            }
        }

        /// <summary>
        /// 清空缓存池，主要用于切换场景时
        /// </summary>
        public void Clear()
        {
            _pool.Clear();
        }
    }
}